import * as lodash from 'lodash';
import dayjs from 'dayjs';
import utils from '.';

/**
 * 判断是否空
 * @param a 参数值
 */
export function isEmpty(a: string | number | null | undefined | any[]): boolean {
    /* 检验字符串类型的 undefined	*/
    if (typeof a === 'undefined') return true;
    /* 检验字符串类型的null */
    if (a === null) return true;
    /* 检验空字符串 */
    if (a === 0 || a === '') return true;
    return false;
}

/**
 * 保留小数位
 * @param val 参数值
 * @param num 小数位
 * @param round 是否四舍五入
 */
export function keepDecimalPlaces(val: any, num = 2, round = false) {
    if (round) {
        return lodash.round(val, num);
    } else {
        return lodash.floor(val, num);
    }
}

/**
 * 获取随机字符串
 * @param len
 * @param type
 */
export function randomStr(len = 8, type = 'alnum'): string {
    let pool = '';
    switch (type) {
        case 'alpha':
            pool = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
            break;
        case 'alnum':
            pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
            break;
        case 'numeric':
            pool = '0123456789';
            break;
        case 'nozero':
            pool = '123456789';
            break;
    }
    // 随机打乱字符串
    let newStr = <string[]>[];
    pool.repeat(Math.ceil(len / pool.length)).split('').forEach((item, index, array) => {
        let newIndex = Math.round(Math.random() * newStr.length);
        newStr.splice(newIndex, 0, item);
    });

    return newStr.join('').substring(0, len);
}

/**
 * 小数位数处理
 * @param value 参数值
 * @param is_round 是否四舍五入
 * @param decimal_num 保留小数位数
 */
export function decimalFormat(value: number, is_round = true, decimal_num = 2) {
    value = Number(value); // 格式转换
    if (value) {
        if (is_round) {
            // 四舍五入保留2位小数（若第二位小数为0，则保留一位小数）数据类型不变
            // console.log(value, '====vvv1');
            // console.log(decimal_num, '====vvv2');
            // console.log(value.toFixed(decimal_num), '====vvv3');
            // return value.toFixed(decimal_num);
            return Number(value.toFixed(decimal_num));
        } else {
            // 不四舍五入 ，向下取整
            return value > 0 ? lodash.floor(value, decimal_num) : lodash.ceil(value, decimal_num);
        }
    }
    return 0;
}

/**
 * 字节格式化
 * @param size 参数值
 */
export function byteFormat(size: number) {
    let units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
    let i: number;
    for (i = 0; size >= 1024 && i < 6; i++) {
        size /= 1024;
    }
    return decimalFormat(size) + units[i];
}

/**
 * 验证手机号
 * @param value
 */
export function phone(value: string): boolean {
    if (value) {
        let regex = /^1[3-9]\d{9}$/;
        return regex.test(value);
    }
    return false;
}

/**
 * 验证前3后4手机号
 * @param value
 */
export function phone2(value: string): boolean {
    if (value) {
        let regex = /^1[3-9]\d{1}\*\*\*\*\d{4}$/;
        return regex.test(value);
    }
    return false;
}

/**
 * 验证小数点后两位金额是否正确
 * @param value
 */
export function money(value: any): boolean {
    if (value) {
        let regex = /^[0-9]+(.[0-9]{1,2})?$/;
        return regex.test(value);
    }
    return false;
}

/**
 * 获取长度
 * @param val 参数值
 */
export function length(val: string): number {
    return isEmpty(val) ? 0 : val.length;
}

/**
 * 序列化
 * @param val
 * @returns
 */
export function toRaw(val: any) {
    return JSON.parse(JSON.stringify(val));
}

/**
 * 转换时间格式
 * @param val
 * @param format
 * @returns
 */
export function toFormatTime(val: any, format = 'YYYY-MM-DD HH:mm') {
    return isEmpty(val) ? '-' : dayjs(val).format(format);
}

/**
 * 数据转化 数组 label-value
 * @param data {1:'aa',2:'bb'}
 * @returns [{label:'xx1',value:1},{label: 'bb',value: 2}]
 */
export function toLabelValueArr(data: object) {
    let result: Array<any> = [];
    for (let i in data) {
        result.push({ label: data[i], value: i });
    }
    return result;
}

/**
 * 生成订单号 18位
 */
export function generateOrderNumber() {
    return dayjs().format("YYYYMMDDHHmmss") + randomStr(4);
}

/**
 * 厘米转换为像素
 * @param val
 * @returns
 */
export function cmConvertToPixel(val: number) {
    return decimalFormat(val / 2.54 * 72, true, 0);
}

/**
 * 将最低值和最高值 转换区间
 * @param min 
 * @param max 
 * @param numStages 
 * @returns 
 */
export function splitRangeIntoStages(min: number, max: number, numStages: number) {
    const interval = (max - min) / numStages;
    let stages: { label: string, start: string, end: string }[] = [];
    console.log(interval, '---->interval');
    for (let i = 0; i < numStages; i++) {
        const stageStart = (min + interval * i + (i ? 1 : 0)).toFixed(0);
        const stageEnd = (min + interval * (i + 1)).toFixed(0);
        stages.push({
            label: `${stageStart}~${stageEnd}`,
            start: stageStart,
            end: stageEnd,
        });
    }

    return stages;
}

/**
 * 判断是否NaN
 * @param value 参数值
 */
export function isNaNValue(value: string | number | null | undefined | any[]): boolean {
    value = Number(value);
    /* 检查 value 是否是 NaN */
    if (typeof value === 'number' && lodash.isNaN(value)) return true;
    /* 检查 value 是否是原始有限数值 */
    if (!lodash.isFinite(value)) return true;

    return false;
}

/**
 * 关于NaN的问题, 安全的加减乘除法并返回结果
 *  
 *  0 / 0 = NaN;
 *  1 + NaN = NaN;
 *  2 * NaN = NaN;
 *  1 / NaN = NaN;
 */
export function accessMath(num1, symbol = '+', num2): number {

    num1 = Number(num1);
    num2 = Number(num2);

    let val = 0;
    if (symbol === '/') {
        // 分母不能为0
        if (isEmpty(num2) || isNaNValue(num2)) {
            return 0;
        }
        val = utils.math.divide(num1, num2);
        return Number(val);
    } 
    
    if (symbol === '+') {
        // 0 + 0
        num1 = isEmpty(num1) || isNaNValue(num1) ? 0 : num1;
        num2 = isEmpty(num2) || isNaNValue(num2) ? 0 : num2;

        val = utils.math.plus(num1, num2);
    } else if (symbol === '-') {
        // 0 - 0
        num1 = isEmpty(num1) || isNaNValue(num1) ? 0 : num1;
        num2 = isEmpty(num2) || isNaNValue(num2) ? 0 : num2;

        val = utils.math.subtract(num1, num2);
    } else if (symbol === '*') {
        // 0 * 0
        num1 = isEmpty(num1) || isNaNValue(num1) ? 0 : num1;
        num2 = isEmpty(num2) || isNaNValue(num2) ? 0 : num2;

        val = utils.math.multiply(num1, num2);
    }

    return Number(val);
}

/**
 * 过滤处理 null 值默认返回空，可指定字段
 * @param obj
 * @param only_keys
 */
export function filterNullEmpty(obj: any[], only_keys: any[]) {
    obj = lodash.mapValues(obj, function (value, key) {
        if (lodash.isEmpty(only_keys)) {
            return value;
        }
        return only_keys.includes(key) && value === null ? '' : value;
    });
    return obj;
}

/**
 * 过滤处理 integer 类型0值默认返回空给前端，可指定字段。
 * 说明：仅特殊处理并不适用普遍情况
 * @param obj
 * @param only_keys
 */
export function filterNumberEmpty(obj: any[], only_keys: any[]) {
    obj = lodash.mapValues(obj, function (value, key) {
        if (lodash.isEmpty(only_keys)) {
            return value;
        }
        return typeof value === 'number' && only_keys.includes(key) && value === 0 ? '' : value;
    });

    return obj;
}

/**
 * 字符串去重
 * @param string 
 * @param separator 
 * @param number 
 */
export function stringUniq(string: string, separator = ',', number = 2) {
    if (lodash.isEmpty(string)) { 
        return '';
    }

    let arr = lodash.split(string, separator, number);
    arr = lodash.uniq(arr);
    return lodash.join(arr, separator);
}